import sys
import pygame
import time
from random import randint

from setting import Setting
from ship import Ship
from bullet import Bullet
from alien import Alien
from game_stats import GameStats
from util.button import Button

class AlienInvasion:
    '''外形人入侵游戏的主程序对象'''
    def __init__(self):
        self.setting = Setting()
        # 初始化主游戏窗口
        pygame.init()
        self.bg_color = self.setting.bg_color
        # self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
        self.screen = pygame.display.set_mode((self.setting.screen_width,self.setting.screen_height))
        pygame.display.set_caption("外星人入侵")
        # 定义帧频时钟
        self.clock = pygame.time.Clock()
        # 定义计数用的实例
        self.stats = GameStats(self)
        self.stats.show_stats()
        # 飞船
        self.ship = Ship(self)
        # 飞船发射的子弹
        self.bullets = pygame.sprite.Group()
        # 外星飞船集合
        self.aliens = pygame.sprite.Group()
        # 当前游戏状态
        self.game_active = False
        # 创建开始按钮
        self.play_btn = Button(self, 'play')

    def _check_events(self):
        '''监听按键信息'''
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = True
                elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = True
                elif event.key == pygame.K_ESCAPE:
                    sys.exit()
                elif event.key == pygame.K_SPACE:
                #    if self.game_active:
                   self._fire_bullet()
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = False
                elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self,mouse_pos):
        '''检查是否点击了开始按钮，并开始游戏'''
        if not self.game_active: 
            if self.play_btn.rect.collidepoint(mouse_pos):
                self.setting.init_setting()
                self.stats.reset_stats()
                self.game_active = True

                self.bullets.empty()
                self.aliens.empty()

                self._create_fleet()
                self.ship.center_ship()
                pygame.mouse.set_visible(False)

    def _create_fleet(self):
        '''创建外星人编队'''
        # 获取外星人的属性
        alien = Alien(self)
        alien_width,alien_height = alien.rect.size

        # 添加N行N列外星人
        current_x, current_y = alien_width+randint(0,40), alien_height
        while current_y < (self.screen.get_height() * 0.6):
            while current_x < (self.screen.get_width() - 2 * alien_width):
                n_alien = Alien(self)
                n_alien.x = current_x
                n_alien.rect.x = current_x
                n_alien.rect.y = current_y
                self.aliens.add(n_alien)
                current_x += 2 * alien_width + randint(0,100)
            current_x = alien_width
            current_y += 2 * alien_height

    def _fire_bullet(self):
        '''飞船开火，发射一枚子弹'''
        if len(self.bullets) < self.setting.bullet_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        '''更新子弹的位置'''
        self.bullets.update()
        # 删除超出边界的子弹
        for bullet in self.bullets.copy():
            if bullet.rect.bottom<=0:
                self.bullets.remove(bullet)
        # 判断是否击中了外星人，并删除对应子弹和飞船
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, False, True)
        # 显示计分
        if collisions:
            temp_score = 0
            for aliens in collisions.values():
                temp_score += self.setting.alien_score * len(aliens)
            self.stats.up_score(temp_score)
        # 判断如果都打完了，则产生一组新的外星人
        if not self.aliens:
            self.bullets.empty()
            self.setting.up_setting()
            self.stats.up_level()
            time.sleep(0.5)   # 等待1秒,再重新开始
            self._create_fleet()

    def _hit_ship(self):
        '''飞船被撞，或者外星人到达底部'''
        if self.stats.ships_left > 0:
            self.stats.ships_left -= 1

            self.bullets.empty()
            self.aliens.empty()

            self._create_fleet()
            self.ship.center_ship()

            time.sleep(0.5)
        else:
            self.game_active = False
            pygame.mouse.set_visible(True)

    def _update_aliens(self):
        '''更新外星人的位置'''
        self.aliens.update()

        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._hit_ship()

        for alien in self.aliens.sprites():
            if alien.rect.bottom >= self.screen.get_height():
                self._hit_ship()
                break

    def _update_screen(self):
        '''刷新界面和显示飞船、子弹、外星人位置'''
        # 清空屏幕
        self.screen.fill(self.bg_color)
        # 显示信息
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.ship.blitme()
        self.aliens.draw(self.screen)
        self.stats.show_stats()
        # 如果游戏没开始，则显示开始按钮
        if not self.game_active:
            self.play_btn.draw_button()

        pygame.display.flip()

    def run_game(self):
        '''启动游戏'''
        speed = self.setting.ship_speed
        while(True):
            self._check_events()

            if self.game_active:
                self.ship.update(speed)
                self._update_bullets()
                self._update_aliens()

            self._update_screen()

            # 设置帧频，1秒刷新60次
            self.clock.tick(60)

if __name__ == '__main__':
    ai = AlienInvasion()
    ai.run_game()
